// var $logManager = require("./LogManager");
// var a = (function () {
//     function t() {}
//     t.shuffle = function (e) {
//         var t;
//         var o;
//         var n = e.slice();
//         var i = n.length;
//         for (var a = i; a--; ) {
//             if (a !== (o = Math.floor(Math.random() * i))) {
//                 t = n[a];
//                 n[a] = n[o];
//                 n[o] = t;
//             }
//         }
//         return n;
//     };
//     t.randomArray = function (e, t, o) {
//         var n = [];
//         var i = [];
//         for (var a = t; a <= o; a++) {
//             n.push(a);
//         }
//         for (; e > 0; e--) {
//             var r = Math.floor(Math.random() * (n.length - 1));
//             i.push(n[r]);
//             n[r] = n[n.length - 1];
//             n.pop();
//         }
//         return i;
//     };
//     t.randomArrayOne = function (e) {
//         return e[this.randomArray(e.length, 0, e.length - 1)[this.random(0, e.length)]];
//     };
//     t.random = function (e, t) {
//         var o = Math.floor(Math.random() * (t - e)) + e;
//         if (o == t) {
//             o -= 1;
//         }
//         return o;
//     };
//     t.deepCopy = function (t) {
//         var o = this;
//         if (!Array.isArray(t)) {
//             throw new TypeError("Input must be an array");
//         }
//         return t.map(function (t) {
//             if (Array.isArray(t)) {
//                 return o.deepCopy(t);
//             } else {
//                 return "object" == typeof t && null !== t ? JSON.parse(JSON.stringify(t)) : t;
//             }
//         });
//     };
//     t.uniqueArray = function (e) {
//         return e.filter(function (e, t, o) {
//             return o.indexOf(e) === t;
//         });
//     };
//     t.removeNull = function (e) {
//         return e.filter(function (e) {
//             return null != e;
//         });
//     };
//     t.randomArrayOneProb = function (e, t) {
//         if (e.length === t.length) {
//             var o = [];
//             for (var n = 0; n < e.length; n++) {
//                 var a = e[n];
//                 var r = t[n];
//                 for (var c = 0; c < r; c++) {
//                     o.push(a);
//                 }
//             }
//             return (o = this.shuffle(o))[this.randomArray(o.length, 0, o.length - 1)[this.random(0, o.length)]];
//         }
//         $logManager.LogMgr.error("随机数组与概率数组长度不一致");
//     };
//     t.getWeightRandom = function (e) {
//         var t = 0;
//         e.forEach(function (e) {
//             return (t += e);
//         });
//         t *= Math.random();
//         for (var o = 0; o < e.length; o++) {
//             if ((t -= e[o]) <= 0) {
//                 return o;
//             }
//         }
//         return 0;
//     };
//     t.findCenterIndex = function (e) {
//         return [Math.floor(e.length / 2), Math.floor(e[0].length / 2)];
//     };
//     t.removeEmpty = function (e) {
//         return e.filter(function (e) {
//             return null != e;
//         });
//     };
//     return t;
// })();
// exports.default = a;


import { LogMgr } from "./LogManager";

/**
 * 工具类，提供各种数组操作方法
 * 建议类名：ArrayUtils
 */
class ArrayUtils {
    constructor() { }

    /**
     * 建议方法名：shuffleArray
     * 打乱数组顺序
     * @param inputArray 输入数组
     * @returns 打乱顺序后的新数组
     */
    static shuffleArray(inputArray: any[]): any[] {
        let tempElement: any;
        let randomIdx: number;
        const shuffledArray = inputArray.slice();
        const arrayLength = shuffledArray.length;
        for (let currentIndex = arrayLength; currentIndex--;) {
            if (currentIndex !== (randomIdx = Math.floor(Math.random() * arrayLength))) {
                tempElement = shuffledArray[currentIndex];
                shuffledArray[currentIndex] = shuffledArray[randomIdx];
                shuffledArray[randomIdx] = tempElement;
            }
        }
        return shuffledArray;
    }

    /**
     * 建议方法名：generateRandomArray
     * 生成指定范围内的随机数组
     * @param length 数组长度
     * @param minValue 最小值
     * @param maxValue 最大值
     * @returns 随机数组
     */
    static generateRandomArray(length: number, minValue: number, maxValue: number): number[] {
        const rangeArray: number[] = [];
        const randomArray: number[] = [];
        for (let value = minValue; value <= maxValue; value++) {
            rangeArray.push(value);
        }
        while (length > 0) {
            const randomIdx = Math.floor(Math.random() * (rangeArray.length - 1));
            randomArray.push(rangeArray[randomIdx]);
            rangeArray[randomIdx] = rangeArray[rangeArray.length - 1];
            rangeArray.pop();
            length--;
        }
        return randomArray;
    }

    /**
     * 建议方法名：getRandomElement
     * 从数组中随机选择一个元素
     * @param inputArray 输入数组
     * @returns 随机选择的元素
     */
    static getRandomElement(inputArray: any[]): any {
        return inputArray[this.generateRandomArray(inputArray.length, 0, inputArray.length - 1)[this.random(0, inputArray.length)]];
    }

    /**
     * 建议方法名：generateRandomNumber
     * 生成指定范围内的随机数
     * @param minValue 最小值
     * @param maxValue 最大值
     * @returns 随机数
     */
    static random(minValue: number, maxValue: number): number {
        let randNumber = Math.floor(Math.random() * (maxValue - minValue)) + minValue;
        if (randNumber == maxValue) {
            randNumber -= 1;
        }
        return randNumber;
    }

    /**
     * 建议方法名：deepCloneArray
     * 深拷贝数组
     * @param inputArray 输入数组
     * @returns 深拷贝后的新数组
     */
    static deepClone(inputArray: any[]): any[] {
        if (!Array.isArray(inputArray)) {
            throw new TypeError("Input must be an array");
        }
        return inputArray.map(item => {
            if (Array.isArray(item)) {
                return this.deepClone(item);
            } else {
                return typeof item === 'object' && item !== null ? JSON.parse(JSON.stringify(item)) : item;
            }
        });
    }

    /**
     * 建议方法名：uniqueElements
     * 数组去重
     * @param inputArray 输入数组
     * @returns 去重后的新数组
     */
    static uniqueElements(inputArray: any[]): any[] {
        return inputArray.filter((element, index, selfArray) => selfArray.indexOf(element) === index);
    }

    /**
     * 建议方法名：removeNullElements
     * 移除数组中的 null 元素
     * @param inputArray 输入数组
     * @returns 移除 null 元素后的新数组
     */
    static removeNullElements(inputArray: any[]): any[] {
        return inputArray.filter(element => element != null);
    }

    /**
     * 建议方法名：getRandomElementByProbability
     * 根据概率从数组中随机选择一个元素
     * @param inputArray 输入数组
     * @param probabilities 概率数组
     * @returns 随机选择的元素
     */
    static getRandomElementByProbability(inputArray: any[], probabilities: number[]): any {
        if (inputArray.length === probabilities.length) {
            let weightedArray: any[] = [];
            for (let i = 0; i < inputArray.length; i++) {
                const element = inputArray[i];
                const probability = probabilities[i];
                for (let j = 0; j < probability; j++) {
                    weightedArray.push(element);
                }
            }
            weightedArray = this.shuffleArray(weightedArray);
            return weightedArray[this.generateRandomArray(weightedArray.length, 0, weightedArray.length - 1)[this.random(0, weightedArray.length)]];
        }
        LogMgr.error("随机数组与概率数组长度不一致");
    }

    /**
     * 建议方法名：getWeightedRandomIndex
     * 根据权重从数组中随机选择一个索引
     * @param weightArray 权重数组
     * @returns 随机选择的索引
     */
    static getWeightedRandomIndex(weightArray: number[]): number {
        let totalWeight = 0;
        weightArray.forEach(weight => totalWeight += weight);
        totalWeight *= Math.random();
        for (let index = 0; index < weightArray.length; index++) {
            if ((totalWeight -= weightArray[index]) <= 0) {
                return index;
            }
        }
        return 0;
    }

    /**
     * 建议方法名：getCenterIndex
     * 找到数组的中心索引
     * @param input2DArray 输入二维数组
     * @returns 中心索引
     */
    static getCenterIndex(input2DArray: any[][]): number[] {
        return [Math.floor(input2DArray.length / 2), Math.floor(input2DArray[0].length / 2)];
    }

    /**
     * 建议方法名：removeEmptyElements
     * 移除数组中的空元素
     * @param inputArray 输入数组
     * @returns 移除空元素后的新数组
     */
    static removeEmptyElements(inputArray: any[]): any[] {
        return inputArray.filter(element => element != null);
    }
}

export default ArrayUtils;